/*
 *  AsyncBufferSystemTester.cpp
 *  Common UnitTest
 *
 *  Created by jiro on 12/04/02.
 *  Copyright 2012 jiro music. All rights reserved.
 *
 */

#include "AsyncBufferSystemTester.h"

#include "../../Common/UtilitySystem/AsyncBufferSystem.h"

#include "../../Common/DebugSystem.h"

#include <vector>

namespace sc
{
	namespace ut
	{
		class Observer : public IObserver< Buffer >
		{
		public:

			Observer() : notifyCount( 0 ) {}

			void Notify( const Buffer* buffer )
			{
//				cout << buffer->dataPtr[ 0 ] << "\n";
				notifyCount++;
				for ( int i = 0, count = buffer->byteCount; i < count; i++ )
				{
					data.push_back( buffer->dataPtr[ i ] );
				}
			}

			int GetNotifyCount() const { return notifyCount; }

			const std::vector< uint8_t >& GetData() const { return data; }

		private:

			int notifyCount;

			std::vector< uint8_t > data;

		};
	}

	void AsyncBufferSystemTester::TestAll()
	{
		Test_AsyncBufferSystem000();
		Test_AsyncBufferSystem001();
		Test_AsyncBufferSystem002();
		Test_AsyncBufferSystem003();
	}

	void AsyncBufferSystemTester::Test_AsyncBufferSystem000()
	{
		const int dataByteCount = 4;
		uint8_t data[ dataByteCount ] = { 0x00, 0x01, 0x02, 0x03 };
		sc::ut::Observer observer;
		AsyncBufferSystem asyncBuffer( dataByteCount, 1 );		
		asyncBuffer.AddObserver( observer );
		asyncBuffer.StartPolling();
		asyncBuffer.WriteData( data , dataByteCount );
		asyncBuffer.StopPolling();

		AssertEqual( observer.GetNotifyCount(), 1 );

		const std::vector< uint8_t > dataGotten = observer.GetData();
		AssertEqual( dataGotten.size(), 4 );
		for ( int i = 0; i < dataByteCount; i++ )
		{
			AssertEqual( dataGotten[ i ], i );
		}
	}

	void AsyncBufferSystemTester::Test_AsyncBufferSystem001()
	{
		const int dataByteCount = 4;
		uint8_t data[ dataByteCount ] = { 0x00, 0x01, 0x02, 0x03 };
		uint8_t data2[ dataByteCount ] = { 0x04, 0x05, 0x06, 0x07 };
		uint8_t data3[ dataByteCount ] = { 0x08, 0x09, 0x0a, 0x0b };
		sc::ut::Observer observer;

		AsyncBufferSystem asyncBuffer( dataByteCount, 1 );		
		asyncBuffer.AddObserver( observer );
		asyncBuffer.StartPolling();
		asyncBuffer.WriteData( data, dataByteCount );
		asyncBuffer.WriteData( data2 , dataByteCount );
		asyncBuffer.WriteData( data3, dataByteCount );
		asyncBuffer.StopPolling();
	
		const std::vector< uint8_t > dataGotten = observer.GetData();
		AssertEqual( dataGotten.size(), 3 * dataByteCount );
		for ( int i = 0; i < 3 * dataByteCount; i++ )
		{
			AssertEqual( dataGotten[ i ], i );
		}
	}
	
	void AsyncBufferSystemTester::Test_AsyncBufferSystem002()
	{
		const int dataByteCount = 8;
		const int bufferCount = 4;
		sc::ut::Observer observer;

		uint8_t data[ 256 ] = { 0 };
		for ( int i = 0; i < 256; i++ )
		{
			data[ i ] = i;
 		}
		
		AsyncBufferSystem asyncBuffer( dataByteCount, bufferCount );		
		asyncBuffer.AddObserver( observer );
		for ( int i = 0; i < 32; i ++ )
		{	//	write data before starting polling
			asyncBuffer.WriteData( data + i * dataByteCount, dataByteCount );
		}
		asyncBuffer.StartPolling();
		asyncBuffer.StopPolling();

		AssertEqual( observer.GetNotifyCount(), 32 );
		const std::vector< uint8_t > dataGotten = observer.GetData();
		AssertEqual( dataGotten.size(), 256 );
		for ( int i = 0; i < 256; i++ )
		{
			AssertEqual( dataGotten[ i ], data[ i ] );
		}		
	}

	void AsyncBufferSystemTester::Test_AsyncBufferSystem003()
	{
		const int dataByteCount = 8;
		const int bufferCount = 4;
		sc::ut::Observer observer;

		uint8_t data[ 256 ] = { 0 };
		for ( int i = 0; i < 256; i++ )
		{
			data[ i ] = i;
 		}

		AsyncBufferSystem asyncBuffer( dataByteCount, bufferCount );		
		asyncBuffer.AddObserver( observer );
		asyncBuffer.StartPolling();
		for ( int i = 0; i < 32; i ++ )
		{
			asyncBuffer.WriteData( data + i * dataByteCount, dataByteCount );
		}
		asyncBuffer.StopPolling();

		AssertEqual( observer.GetNotifyCount(), 32 );
		const std::vector< uint8_t > dataGotten = observer.GetData();
		AssertEqual( dataGotten.size(), 256 );
		for ( int i = 0; i < 256; i++ )
		{
			AssertEqual( dataGotten[ i ], data[ i ] );
		}
	}
}


